package com.iim.caffe;

import java.io.IOException;
import java.nio.file.Files;
import java.io.File;
import java.nio.file.Paths;
import java.nio.file.Path;

public class LoadLibraryModule {
    public native byte[] people_face_detection(byte[] image_data, int[] face_region, float[] feature, jint model_version, long code_ret[]);
    public native int recognition_face(byte[] image_data, float[][] feature, long code_ret[]);
    public native int camera_face(float[][] feature);
    public native boolean play_audio(String[] user_name);
    public native boolean play_warnig(String content);
    public native boolean recognition_start();

    public static void main(String[] args) {
        LoadLibraryModule extract_feature = new LoadLibraryModule();
        System.loadLibrary("face_feature_extract");

        long startTime=System.currentTimeMillis();
        int feature_length = 512;
        int feature_db_num = 1000;
        int[] face_region = new int[4];  // x, y width, height
        float[][] feature_db = new float[feature_db_num][feature_length];
        String[] feature_db_name = new String[feature_db_num];
        float[][] feature = new float[10][feature_length];
        float[] feature_registion = new float[feature_length];
        long[] code_ret = new long[1];

        int try_times = 1;
        File image_path = new File("./image");
        File[] array = image_path.listFiles();
        if(array.length == 0) {
            System.out.println("None image found in current directory!");
        }
        int feature_db_index = 0;
        for(int j = 0; j < array.length && j < feature_db_num && j < 5; j++){
            if(!array[j].isFile()) continue;
            if(array[j].getName().lastIndexOf(".jpg") < 0 && array[j].getName().lastIndexOf(".png") < 0) continue;
            System.out.println(array[j].getName());
            byte[] image_data;
            Path path = Paths.get("./image/" + array[j].getName());
            try {
                image_data = Files.readAllBytes(path);
            } catch (IOException e) {
                System.out.println("Got a Exception：" + e.getMessage());
                return;
            }

            for(int i = 0; i < try_times; i++) {
                System.out.printf("try_times: %d\n", i);
                byte[] face_patch_image = extract_feature.people_face_detection(image_data, face_region, feature_registion, 0, code_ret);
                System.out.printf("try_times: %d\n", i);
                Path face_patch_image_path = Paths.get("/home/iim/face_patch_image.jpg");
                try {
                    Files.write(face_patch_image_path, face_patch_image);
                } catch (IOException e) {
                    System.out.println("Got a Exception：" + e.getMessage());
                    return;
                }
                if(code_ret[0] == 1000){
                    for(int kk = 0; kk < feature_length; kk++){
                        feature_db[feature_db_index][kk] = feature_registion[kk];
                    }
                    String[] filePathSplit = array[j].getName().split("\\.");
                    feature_db_name[feature_db_index] = filePathSplit[0];
                    System.out.println(feature_db_index + " name " + filePathSplit[0]);
                    feature_db_index += 1;
                } else {
                    System.out.println(array[j].getName() + " code:" + code_ret[0] + ", face region: " + face_region[0] +
                                       ", " + face_region[1] + ", " + face_region[2] + ", " + face_region[3] + " \n");
                }
            }
        }
        System.out.println("feature num in db: " + feature_db_index);
        for(int j = 0; j < 10000000; j++){
            if(true){
                byte[] image_data_test;
                Path path = Paths.get("./image/cj.png");
                try {
                    image_data_test = Files.readAllBytes(path);
                } catch (IOException e) {
                    System.out.println("Got a Exception：" + e.getMessage());
                    return;
                }
                int face_count = extract_feature.recognition_face(image_data_test, feature, code_ret);
                System.out.println("face_count: " + face_count + " code:" + code_ret[0]);
                extract_feature.play_warnig("测试");
            } else {
                int face_detection_result = extract_feature.camera_face(feature);
                System.out.println("detect face num: " + face_detection_result);
                String[] user_name =new String[10];
                for(int m = 0; m < face_detection_result; m++){
                    for(int n = 0; n < 10; n++){
                        //System.out.println(feature[m][n]);
                    }
                    float max_score = -99;
                    int max_score_index = -1;
                    for(int i = 0; i < feature_db_index; i++){
                        float current_score = 0;
                        for(int k = 0; k < feature_length; k++){
                            current_score += (feature_db[i][k] * feature[m][k]);
                        }
                        if(current_score > max_score){
                            max_score = current_score;
                            max_score_index = i;
                        }
                    }
                    System.out.println("recognition score: " + max_score + " name: " + feature_db_name[max_score_index]);
                    if(max_score >= 0.42){
                        user_name[m] = feature_db_name[max_score_index];
                    } else {
                        user_name[m] = "";
                    }
                }
            boolean return_result = extract_feature.play_audio(user_name);
            //System.out.println("play_audio return: " + return_result + " name " + user_name[0]);
            }
        }

        long endTime=System.currentTimeMillis();
        System.out.printf("\n");
        for(int i = 0; i < feature_length; i++) {
            //System.out.printf("%f ", feature[i]);
        }

        System.out.printf("\n");
        System.out.println("total time: " + (endTime - startTime) + " ms, per image: " + ((endTime - startTime) / try_times) + "ms");
    }
}
